package com.retailcloud.baseservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.retailcloud.baseservice.dao.TenantsDao;
import com.retailcloud.baseservice.dao.UsersDao;

import com.retailcloud.baseservice.entity.TenantsEntity;
import com.retailcloud.baseservice.entity.UsersEntity;
import com.retailcloud.baseservice.service.TokenService;
import com.retailcloud.commonutils.constant.UserRedisKeyConstant;
import com.retailcloud.commonutils.dto.TenantsDTO;
import com.retailcloud.commonutils.dto.UserDTO;
import com.retailcloud.commonutils.utils.RedisUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;

import static com.retailcloud.commonutils.utils.RedisUtils.DEFAULT_EXPIRE;

/**
 * @author wudi
 * @date 2024/11/5
 * @comment
 */
@Service
public class TokenServiceImpl implements TokenService {

    @Autowired
    private RedisUtils redisUtils;

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private long expiration;

    @Autowired
    UsersDao usersDao;
    @Autowired
    TenantsDao tenantsDao;

    @Override
    public String generateToken(String username,String jsonUserInfo) {
        String token = Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();

        // 存储 token 到 Redis
        redisUtils.set(UserRedisKeyConstant.USER_WECHAT_TOKEN_KEY + username, token, DEFAULT_EXPIRE);
        redisUtils.set(UserRedisKeyConstant.USER_TOKEN_USER_KEY + username, jsonUserInfo);
        return token;
    }

    @Override
    public boolean validateToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();

            String username = claims.getSubject();
            if (username == null || username.isEmpty()) {
                return false;
            }

            // 检查 token 是否存在于 Redis 中
            String storedToken = redisUtils.get(UserRedisKeyConstant.USER_WECHAT_TOKEN_KEY + username);
            return storedToken != null && storedToken.equals(token);
        } catch (Exception e) {
            return false;
        }
    }
    @Override
    public String refreshToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();

            String username = claims.getSubject();
            if (username == null || username.isEmpty()) {
                return null;
            }

            // 生成新的 token
            String newToken = Jwts.builder()
                    .setSubject(username)
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(System.currentTimeMillis() + expiration))
                    .signWith(SignatureAlgorithm.HS512, secret)
                    .compact();

            // 更新 Redis 中的 token
            redisUtils.set(UserRedisKeyConstant.USER_WECHAT_TOKEN_KEY + username, newToken, DEFAULT_EXPIRE);
            //刷新用户缓存信息
            UserDTO userDTO = new UserDTO();
            QueryWrapper<UsersEntity> usersEntityQueryWrapper = new QueryWrapper<>();
            usersEntityQueryWrapper.eq("wechat_openid", username);
            usersEntityQueryWrapper.last("limit 1");
            UsersEntity usersEntity = usersDao.selectOne(usersEntityQueryWrapper);
            if (usersEntity != null) {
                BeanUtils.copyProperties(usersEntity, userDTO);
                // 查询企业信息
                if (StringUtils.isNotBlank(usersEntity.getTenantId())) {
                    QueryWrapper<TenantsEntity> tenantsEntityQueryWrapper = new QueryWrapper<>();
                    tenantsEntityQueryWrapper.eq("tenant_id", usersEntity.getTenantId());
                    tenantsEntityQueryWrapper.last("limit 1");
                    TenantsEntity tenantsEntity = tenantsDao.selectOne(tenantsEntityQueryWrapper);
                    TenantsDTO tenantsDTO = new TenantsDTO();
                    BeanUtils.copyProperties(tenantsEntity, tenantsDTO);
                    userDTO.setTenants(tenantsDTO);
                }
            }
            redisUtils.set("tokenUserInfo:" + username, JSONObject.toJSONString(userDTO));
            return newToken;
        } catch (Exception e) {
            return null;
        }
    }
}
